// 定义工具类所在的包
package com.zhunaer.utils;

// 导入用于读取输入流的类，用于加载配置文件
import java.io.InputStream;
// 导入 JDBC 相关的类，用于数据库连接和操作
import java.sql.*;
// 导入用于处理属性文件的类
import java.util.Properties;

/**
 * JDBCUtils 类是一个工具类，用于简化 JDBC 操作。
 * 它包含加载数据库配置、获取数据库连接、关闭数据库资源以及事务管理等方法。
 */
public class JDBCUtils {
    // 数据库驱动类名
    private static String driver;
    // 数据库连接的 URL
    private static String url;
    // 数据库用户名
    private static String username;
    // 数据库密码
    private static String password;

    // 静态代码块，在类加载时执行，用于初始化数据库配置
    static {
        try {
            // 通过类加载器获取 db.properties 配置文件的输入流
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
            // 创建 Properties 对象来加载配置文件内容
            Properties prop = new Properties();
            // 从输入流中加载配置文件
            prop.load(is);

            // 从配置文件中获取数据库驱动类名
            driver = prop.getProperty("jdbc.driver");
            // 从配置文件中获取数据库连接 URL
            url = prop.getProperty("jdbc.url");
            // 从配置文件中获取数据库用户名
            username = prop.getProperty("jdbc.username");
            // 从配置文件中获取数据库密码
            password = prop.getProperty("jdbc.password");

            // 加载数据库驱动类
            Class.forName(driver);
        } catch (Exception e) {
            // 若加载配置文件或驱动类失败，抛出运行时异常
            throw new RuntimeException("数据库配置加载失败", e);
        }
    }

    /**
     * 获取数据库连接。
     *
     * @return 返回一个数据库连接对象
     * @throws SQLException 若获取连接时发生 SQL 异常
     */
    public static Connection getConnection() throws SQLException {
        // 使用 DriverManager 根据配置信息获取数据库连接
        return DriverManager.getConnection(url, username, password);
    }

    /**
     * 关闭数据库连接、语句对象和结果集对象。
     *
     * @param conn 数据库连接对象
     * @param stmt 语句对象
     * @param rs   结果集对象
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        try {
            // 若结果集不为空，关闭结果集
            if (rs != null) {
                rs.close();
            }
            // 若语句对象不为空，关闭语句对象
            if (stmt != null) {
                stmt.close();
            }
            // 若数据库连接不为空
            if (conn != null) {
                // 若连接处于手动提交事务模式，将其恢复为自动提交模式
                if (!conn.getAutoCommit()) {
                    conn.setAutoCommit(true);
                }
                // 关闭数据库连接
                conn.close();
            }
        } catch (SQLException e) {
            // 若关闭资源时发生 SQL 异常，打印异常堆栈信息
            e.printStackTrace();
        }
    }

    /**
     * 开启数据库事务。
     *
     * @param conn 数据库连接对象
     * @throws SQLException 若设置自动提交为 false 时发生 SQL 异常
     */
    public static void beginTransaction(Connection conn) throws SQLException {
        // 将数据库连接的自动提交模式设置为 false，开启事务
        conn.setAutoCommit(false);
    }

    /**
     * 提交数据库事务。
     *
     * @param conn 数据库连接对象
     */
    public static void commitTransaction(Connection conn) {
        try {
            // 若连接不为空且处于手动提交事务模式
            if (conn != null && !conn.getAutoCommit()) {
                // 提交事务
                conn.commit();
                // 将连接恢复为自动提交模式
                conn.setAutoCommit(true);
            }
        } catch (SQLException e) {
            // 若提交事务时发生 SQL 异常，打印异常堆栈信息
            e.printStackTrace();
        }
    }

    /**
     * 回滚数据库事务。
     *
     * @param conn 数据库连接对象
     */
    public static void rollbackTransaction(Connection conn) {
        try {
            // 若连接不为空且处于手动提交事务模式
            if (conn != null && !conn.getAutoCommit()) {
                // 回滚事务
                conn.rollback();
                // 将连接恢复为自动提交模式
                conn.setAutoCommit(true);
            }
        } catch (SQLException e) {
            // 若回滚事务时发生 SQL 异常，打印异常堆栈信息
            e.printStackTrace();
        }
    }
}